package com.changgou.exception;


import com.changgou.common.CommonCode;
import com.changgou.common.ResultCode;
import com.google.common.collect.ImmutableMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;


/*
 全局捕获异常
 */
@ControllerAdvice
public class GlobalExceptionCatch {

    //日志收集
    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionCatch.class);

    // 使用exceptions 存放异常类型和错误代码的映射，ImmutableMap的特点是已经创建不能更改，且线程安全
    private static ImmutableMap<Class<? extends Throwable>, ResultCode> EXCEPTIONS;

    // 使用builder来构建一个异常类型和错误代码
    private static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder = ImmutableMap.builder();

    @ResponseBody
    @ExceptionHandler(CustomException.class)
    public ResultCode catchCustomException(CustomException customException){
         LOGGER.error("catch exception: {}",customException.getResultCode());
        return customException.getResultCode();
    }


     @ExceptionHandler(Exception.class)
     public ModelAndView exception(Exception e){
        LOGGER.error("catch exception: {}",e.getClass(),e);
        ModelAndView mv = new ModelAndView();

        if(EXCEPTIONS == null){
            EXCEPTIONS = builder.build(); //构建异常信息
        }
        final ResultCode resultCode = EXCEPTIONS.get(e.getClass()); //获取异常信息
        if(resultCode != null){
            mv.addObject("msg",resultCode);

        }else{
            mv.addObject("msg", CommonCode.SERVER_ERROR);
        }
         return mv;
     }

     static {
        builder.put(NullPointerException.class,CommonCode.SERVER_ERROR);
     }

}
